<?php
/**
 * | 节程 [ 节程赋能开发者，助力企业发展 ]
 * +----------------------------------------------------------------------
 *  | Copyright (c) 2020~2029 温州惊蛰网络科技有限公司 All rights reserved.
 * +----------------------------------------------------------------------
 *  | Licensed 节程并不是自由软件，未经许可不能去掉节程相关版权
 * +----------------------------------------------------------------------
 */
declare (strict_types=1);

namespace app\index\service;

use app\index\model\Agent;
use app\index\model\AgentApply;
use app\index\model\AgentBillTemporary;
use app\index\model\AgentWithdraw;
use app\index\model\Assistant;
use app\index\model\Configuration;
use app\index\model\FormAnswer;
use app\index\model\IntegralRecord;
use app\index\model\Merchant;
use app\index\model\MyCollect;
use app\index\model\NewKidGift;
use app\index\model\Order;
use app\index\model\OrderEvaluate;
use app\index\model\RechargeRecord;
use app\index\model\User;
use app\index\model\User as admin;
use app\index\model\UserAddress;
use app\index\model\UserCard;
use app\index\model\UserCash;
use app\index\model\UserCoupon;
use app\index\model\UserWx;
use app\index\model\view\AgentStatistics;
use app\index\validate\UserValidate;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\exception\HttpException;
use think\facade\Cache;
use think\facade\Db;

class UserService
{
    private $mid;

    public function __construct()
    {
        global $mid;
        $this->mid = $mid;
        $this->validate = new UserValidate();
    }

    public function agent($agentId)
    {
        $model = admin::where('agent_id', $agentId)->field(['nickname', 'picurl'])->find();
        return [HTTP_SUCCESS, $model];
    }

    public function read(int $id)
    {
        $model = admin::find($id);
        return [HTTP_SUCCESS, $model];
    }


    public function update(int $id, array $data)
    {
        $update_time = $data['update_time'];
        unset($data['update_time']);
        $admin = admin::where('update_time', $update_time)
            ->where('id', $id)
            ->where('mall_id', $this->mid)
            ->save($data);
        return [HTTP_CREATED, $admin];
    }


    public function delete($id)
    {
        admin::destroy($id);
        return HTTP_NOCONTEND;
    }


    public function register(array $data, int $id)
    {
        global $token;
        if (empty(Cache::get(checkRedisKey((string)$data['mobile']))) || $data['code'] != Cache::get(checkRedisKey((string)$data['mobile'])))
            throw new Exception('验证码错误', HTTP_INVALID);
        $up = User::update(['name' => $data['name'] ?? null, 'mobile' => $data['mobile']], ['id' => $id]);
// 合并
//        $other = User::where("mobile", $data['mobile'])->where('id', "<>", $id)->find();
//        if (!empty($other)) {
//            $ee = $this->upUserData($id);
//        }
        $find = User::find($id);
        Cache::store('redis')->delete("INDEX:" . $token . "-" . $find['mall_id']);
        Cache::store('redis')->set("INDEX:" . $token . "-" . $find['mall_id'], json_encode($find), 60 * 60 * 24 * 30);
        return [HTTP_SUCCESS, $up];
    }


    public function getMorePhone()
    {
        global $user;
        if (empty($user['mobile'])) return [HTTP_SUCCESS, null];
        $mobiles = User::with('userWx')->where('a.mobile', $user['mobile'])
            ->where('a.mall_id', $user['mall_id'])
            ->alias('a')
            ->join('user_cash u', 'a.id=u.user_id', 'LEFT')
            ->field('
            a.id,a.picurl,a.nickname,a.mobile,
            IFNULL(u.total,0.00) as total,IFNULL(u.integral,0) as integral_total,a.agent_id
            ')
            ->group('a.id')
            ->select()
            ->toArray();
        foreach ($mobiles as $k => $v) {
            $mobiles[$k]['order_count'] = Order::where('user_id', $v['id'])->count();
            $mobiles[$k]['coupon_count'] = UserCoupon::where('user_id', $v['id'])->where('status', 0)->count();
            $mobiles[$k]['team_count'] = AgentStatistics::where('user_id', $v['id'])->value('team');
        }
        return [HTTP_SUCCESS, $mobiles];
    }

    public function upUserData($id)
    {
        $token = request()->header('Authorization');
        $user = User::find($id);
        $user_agent = Agent::where('user_id', $id)->find();
        if (empty($user['mobile'])) throw new Exception("手机号码为空！", HTTP_UNAUTH);
        $user_arr = User::where('mobile', $user['mobile'])->where('id', '<>', $id)->where('mall_id', $user['mall_id'])->select()->toArray();
        $ids = array_column($user_arr, 'id');
        $arr = UserCash::where('user_id', 'IN', $ids)->where('mall_id', $user['mall_id'])->select()->toArray();
        $ids_agent = Agent::where('user_id', 'IN', $ids)->select();
        if (!empty($ids_agent)) {
            $ids_agent = $ids_agent->toArray();
            $agenids = array_column($ids_agent, 'id');
            //分销体现
            AgentWithdraw::where('agent_id', 'IN', $agenids)->update(['agent_id' => $user_agent['id']]);
        }
        $find_cash = UserCash::where('user_id', $user['id'])->find()->toArray();
        foreach ($arr as $v) {
            if (isset($v['total'])) $find_cash['total'] += $v['total'];
            if (isset($v['recharge'])) $find_cash['recharge'] += $v['recharge'];
            if (isset($v['expense'])) $find_cash['expense'] += $v['expense'];
            if (isset($v['withdraw'])) $find_cash['withdraw'] += $v['withdraw'];
            if (isset($v['agent_total'])) $find_cash['agent_total'] += $v['agent_total'];
            if (isset($v['agent'])) $find_cash['agent'] = $v['agent'];
            if (isset($v['agent_withdraw'])) $find_cash['agent_withdraw'] += $v['agent_withdraw'];
            if (isset($v['integral_total'])) $find_cash['integral_total'] += $v['integral_total'];
            if (isset($v['integral'])) $find_cash['integral'] += $v['integral'];
            if (isset($v['integral_withdraw'])) $find_cash['integral_withdraw'] += $v['integral_withdraw'];
        }
        unset($find_cash['user_id'], $find_cash['mall_id']);
        UserCash::update($find_cash, ['user_id' => $id]);
        $where[] = ['user_id', 'IN', $ids];
        $where[] = ['mall_id', '=', $user['mall_id']];
        $up = ['user_id' => $id];

        //钱包数据删除
        UserCash::where($where)->delete();
        //用户的优惠券
        UserCoupon::where($where)->update($up);
        //收藏
        $commoditys = MyCollect::where($where)->field('commodity_id,id')->select();
        if (!empty($commoditys)) $commoditys = $commoditys->toArray();
        $arr = array_column($commoditys, 'commodity_id');
        $commodity_ids = array_unique($arr);
        $collect_ids = array_column($commoditys, 'id');
        MyCollect::destroy($collect_ids);
        foreach ($commodity_ids as $v) {
            MyCollect::create(['mall_id' => $user['mall_id'], 'user_id' => $id, 'commodity_id' => $v]);
        }
        //订单
        Db::name('order')->where($where)->update(['user_id' => $id]);
        //评价
        OrderEvaluate::where($where)->update($up);
        //收货地址
        UserAddress::where($where)->update($up);

        //分销
        Agent::where($where)->useSoftDelete('delete_time', date('Y-m-d H:i:s', time()))->delete();
        Agent::where('pid', 'IN', $ids)->update(['pid' => 0]);//修改下级
        //商户
        Merchant::where($where)->update($up);
        //积分
        IntegralRecord::where($where)->update($up);
        //新人领取礼物记录
        NewKidGift::where($where)->update($up);
        //自定义表格
        FormAnswer::where($where)->update($up);
        //卡号
        UserCard::where($where)->update($up);
        //微信
        UserWx::where($where)->update($up);
        //提成表
        $result = $up;
        $result['agent_id'] = $user_agent['id'];
        AgentBillTemporary::where($where)->update($result);
        AgentBillTemporary::where('source_user_id', 'IN', $ids)->where('mall_id', $user['mall_id'])->update(['source_user_id' => $id]);
        //核销员
        Assistant::where($where)->update($up);
        //余额明细
        RechargeRecord::where($where)->update($up);
        //用户
        User::where('id', 'IN', $ids)->where('mall_id', $user['mall_id'])->update(['is_merge' => 1]);
        User::where('id', $id)->update(['is_success' => 1]);
//        User::where('id', 'IN', $ids)->delete();
        User::where('id', "IN", $ids)->update(['delete_time' => date("Y-m-d H:i:s")]);

        Cache::store('redis')->delete("INDEX:" . $token . "-" . $user['mall_id']);
        foreach ($ids as $v) {
            $wxa_token = Cache::store('redis')->get(checkRedisKey("TOKEN:" . $v));
            $wxa_token1 = Cache::store('redis')->get("TOKEN:" . $v);
            Cache::store('redis')->delete('INDEX:' . $wxa_token . "-" . $user['mall_id']);
            Cache::store('redis')->delete('INDEX:' . $wxa_token1 . "-" . $user['mall_id']);
        }
        $news = User::find($id);
        Cache::store('redis')->set("INDEX:" . $token . "-" . $news['mall_id'], json_encode($news), 60 * 60 * 24 * 30);

        return [HTTP_SUCCESS, "成功"];
    }


    public function tokenToUserInfo(string $token)
    {
        global $mid;
        $user = Cache::store('redis')->get("INDEX:" . $token . "-" . $mid);
        if (empty($user)) throw new Exception("用户数据为空，请重新登录！", HTTP_UNAUTH);
        $js = json_decode($user, true);
        $find = User::find($js['id']);
        $assistant = Assistant::where('user_id', $js['id'])->find();
        $find['is_write'] = empty($assistant) ? false : true;
        $find['total_money'] = Order::where('status', 4)
            ->sum('money');
        $find['level_money'] = Order::where('status', 4)
            ->where('create_time', '>', empty($find['level_time']) ? '2022-01-01' : $find['level_time'])
            ->sum('money');
        $find['level_money'] = $find['total_money'] - $find['level_money'];
        if ($find['status'] == 2)
            throw new Exception("您已被拉黑,请与客服人员联系!", HTTP_UNAUTH);
        return [HTTP_SUCCESS, $find];
    }


    public function searchPhone(string $phone, int $mall_id)
    {
        $where = ['a.mobile' => $phone, 'a.mall_id' => $mall_id];
        $user = User::where(['b.type' => 1])->where($where)->join('user_wx b', 'a.id=b.user_id', 'LEFT')->alias('a')->value('a.id');
        if (empty($user))
            $user = User::where(['b.type' => 2])->where($where)->join('user_wx b', 'a.id=b.user_id', 'LEFT')->alias('a')->value('a.id');
        return $user;
    }


    public function bindingPhone(int $phone, int $code, int $id): array
    {
        if (empty(Cache::get(checkRedisKey((string)$phone))) || $code != Cache::get(checkRedisKey((string)$phone)))
            throw new Exception('验证码错误', HTTP_INVALID);

        $up = User::update(['mobile' => $phone], ['id' => $id]);
        return [HTTP_SUCCESS, $up];
    }


    public function UserCenter()
    {
        global $user, $mid;
        $configuration = Configuration::where(['type' => "Assettransfer"])->value("configuration");
        $configuration = empty($configuration)? []: json_decode($configuration, true);
        $balance_config = $configuration['balance'] ?? [];
        $integral_config = $configuration['integral'] ?? [];


        $coupons = UserCoupon::where('user_id', $user['id'])->where('status', 0)->where('mall_id', $mid)->count();
        $find = UserCash::where('user_id', $user['id'])->find();
        $data = [
            "coupons" => $coupons ?? 0,
            "integral" => $find['integral'] ?? 0,
            "total" => $find['total'] ?? 0.00,
            'balance_switch' => $balance_config['open'] ?? 0,
            'integral_switch' => $integral_config['open'] ?? 0,
        ];
        return [HTTP_SUCCESS, $data];
    }


    public function setPid(int $pid)
    {
        global $user;
        $find = User::find($user['id']);
        if ($user['id'] == $pid) throw new HttpException(HTTP_INVALID, '不能绑定的自己');
        if (!empty($find['pid'])) throw new HttpException(HTTP_INVALID, "已经绑定推广员ID,不能重复绑定");
        $find->pid = $pid;
        $up = $find->save();
        return [HTTP_SUCCESS, $up];
    }

    /**
     * 更新用户数据
     * @param $data
     * @return array
     * @throws
     */
    public function upUser($data)
    {
        $data['nickname'] = preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $data['nickname']);
        if (mb_strlen($data['nickname']) >= 16) {
            return [HTTP_NOTACCEPT, "昵称太长啦"];
        }
        $up = User::update($data, ['id' => $data['id']]);
        return [HTTP_SUCCESS, $up];
    }

    /**
     * 手机注册登录
     * @param array $data
     * @return array
     * @throws
     */
    public function userRegister($data)
    {
        $data['mall_id'] = $this->mid;
        if (!$this->validate->scene('userRegister')->check($data)) {
            return [HTTP_INVALID, $this->validate->getError()];
        }
        $cahce_code = Cache::get(checkRedisKey((string)$data['mobile']));
        if ($cahce_code != $data['code']) {
            return [HTTP_INVALID, "验证码错误"];
        }
        $find = User::where('mall_id', $data['mall_id'])
            ->where('mobile', $data['mobile'])
            ->whereRaw('id NOT IN (SELECT user_id FROM jiecheng_user_wx)')
            ->find();
        if (empty($find)) {
            $data['password'] = isset($data['password']) ? hash('sha256', strval($data['password'])) : "";
            $data['nickname'] = '用户_' . time() . rand(10, 99);
            $data['picurl'] = '/61465115.jpg';
            $create = User::create($data);
            UserCash::create(['user_id' => $create->id, 'mall_id' => $data['mall_id']]);
            $login = new LoginService();
            $login->agentRegister($create->toArray(), 0);
            $find = User::find($create->id);
        } else {
            if (isset($data['password']) && !empty($data['password'])) {
                $data['password'] = hash('sha256', strval($data['password']));
                if ($find['pid'] > 0) {
                    unset($data['pid']);
                }
                User::update($data, ['id' => $find['id']]);
                $find = User::find($find['id']);
            }
        }
        $token = createToken();
        Cache::store('redis')->set("TOKEN:" . $find['id'], $token, 60 * 60 * 24 * 30);
        Cache::store('redis')->set("INDEX:" . $token . "-" . $data['mall_id'], json_encode($find), 60 * 60 * 24 * 30);
        return [HTTP_SUCCESS, $token];
    }

    /**
     * 手机号登录
     * @param $data 登录数据
     * @return array
     * @throws
     */
    public function login($data)
    {
        $data['mall_id'] = $this->mid;
        if (!$this->validate->scene('userLogin')->check($data)) {
            return [HTTP_INVALID, $this->validate->getError()];
        }
        $find = User::where('mall_id', $data['mall_id'])
            ->where('mobile', $data['mobile'])
            ->whereRaw('id NOT IN (SELECT user_id FROM jiecheng_user_wx)')
            ->find();
        if (empty($find) || $find['password'] != hash('sha256', strval($data['password']))) {
            return [HTTP_INVALID, "账号不存在或密码错误！"];
        }
        if (isset($data['pid']) && !empty($data['pid']) && $find['pid'] == (0 || null)) {
            User::update(['pid' => $data['pid']], ['id' => $find['id']]);
        }
        $token = createToken();
        Cache::store('redis')->set("TOKEN:" . $find['id'], $token, 60 * 60 * 24 * 30);
        Cache::store('redis')->set("INDEX:" . $token . "-" . $data['mall_id'], json_encode($find), 60 * 60 * 24 * 30);
        return [HTTP_SUCCESS, $token];
    }
}
